﻿#if UNITY_EDITOR
using System.Collections;
using UnityEditor;
using UnityEngine;

namespace GameFramework.Agent
{
    [System.Serializable]
    public class SceneViewFollower
    {
        public bool enable;
        public Vector3 positionOffset;
        public bool enableFixedRotation;
        public Vector3 fixedRotation;
        public Transform targetTransform;
        public float size;
        public bool orthographic;
        public int sceneViewIndex;

        public SceneViewFollower()
        {
            enable = false;
            positionOffset = Vector3.zero;
            enableFixedRotation = false;
            fixedRotation = Vector3.zero;
            size = 0.01f;
            orthographic = false;
            sceneViewIndex = 0;
        }
    }

    [ExecuteInEditMode]
    public class SceneAgent : MonoBehaviour
    {
        public bool on = true;
        public bool onlyInPlayMode = false;
        public SceneViewFollower[] sceneViewFollowers;
        private ArrayList sceneViews;

        private void Start()
        {
            if (Camera.main == null)
            {
                return;
            }
            sceneViewFollowers = new SceneViewFollower[2];
            var defFollower = new SceneViewFollower();
            defFollower.enable = false;
            defFollower.targetTransform = Camera.main.transform;
            sceneViewFollowers[0] = defFollower;

            var uiFollower = new SceneViewFollower();
            uiFollower.enable = false;
            uiFollower.size = 11;
            uiFollower.orthographic = true;
            uiFollower.targetTransform = GameObject.Find("Stage Camera").transform;
            sceneViewFollowers[1] = uiFollower;
        }

        void LateUpdate()
        {
            if (sceneViewFollowers != null && sceneViews != null)
            {
                foreach (SceneViewFollower svf in sceneViewFollowers)
                {
                    if (svf.targetTransform == null) svf.targetTransform = transform;
                    svf.size = Mathf.Clamp(svf.size, .01f, float.PositiveInfinity);
                    svf.sceneViewIndex = Mathf.Clamp(svf.sceneViewIndex, 0, sceneViews.Count - 1);
                }
            }

            if (Application.isPlaying)
                Follow();
        }

        public void OnDrawGizmos()
        {
            if (!Application.isPlaying)
                Follow();
        }

        private void Follow()
        {
            sceneViews = UnityEditor.SceneView.sceneViews;
            if (sceneViewFollowers == null || !on || sceneViews.Count == 0) return;

            foreach (SceneViewFollower svf in sceneViewFollowers)
            {
                if (!svf.enable) continue;
                UnityEditor.SceneView sceneView = (UnityEditor.SceneView)sceneViews[svf.sceneViewIndex];
                if (sceneView != null)
                {
                    if ((Application.isPlaying && onlyInPlayMode) || !onlyInPlayMode)
                    {
                        sceneView.orthographic = svf.orthographic;
                        sceneView.LookAtDirect(svf.targetTransform.position + svf.positionOffset, (svf.enableFixedRotation) ? Quaternion.Euler(svf.fixedRotation) : svf.targetTransform.rotation, svf.size);
                    }
                }
            }
        }

        public SceneView GetFollowerSceneView()
        {
            if (sceneViewFollowers.Length <= 0)
            {
                return null;
            }
            for (int i = 0; i < sceneViewFollowers.Length; i++)
            {
                var curFollower = sceneViewFollowers[i];
                if (curFollower == null)
                {
                    continue;
                }
                if (!curFollower.enable)
                {
                    continue;
                }
                var curFollowerIdx = curFollower.sceneViewIndex;
                var sceneViews = SceneView.sceneViews;
                if (sceneViews.Count <= curFollowerIdx)
                {
                    continue;
                }
                var curSceneView = SceneView.sceneViews[curFollowerIdx];
                return (SceneView)curSceneView;
            }
            return null;
        }
    }
}
#endif